package cn.px.rest.controller.mobile;

import cn.hutool.core.date.DateUtil;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.constant.CommonConstants;
import cn.px.common.util.FileUtils;
import cn.px.common.util.IdGeneratorUtils;
import cn.px.common.util.R;
import cn.px.common.validation.group.AddGroup;
import cn.px.common.validation.group.UpdateGroup;
import cn.px.dao.dto.check.CheckJobDTO;
import cn.px.dao.dto.repair.RepairApplicationFormDTO;
import cn.px.dao.dto.sb.SbInfoDTO;
import cn.px.dao.dto.sb.SbStatusLogDTO;
import cn.px.dao.enums.CheckStandardTypeEnum;
import cn.px.dao.vo.FileVO;
import cn.px.dao.vo.index.GatherTaskVO;
import cn.px.dao.vo.query.check.CheckJobVO;
import cn.px.dao.vo.sb.SbInfoVO;
import cn.px.rest.log.annotation.SysLog;
import cn.px.service.check.CheckJobService;
import cn.px.service.repair.RepairApplicationFormService;
import cn.px.service.sb.SbInfoService;
import cn.px.service.sb.SbStatusLogService;
import cn.px.service.upms.SysFileService;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;

/**
 * @Description 移动端不需要登录的接口，注意这里不能使用getUserInfo方法，该方法需要登录
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2019,北京乾元坤和科技有限公司 All rights reserved.
 */
@RestController
@RequestMapping("/ignores")
public class IgnoreController {
    @Value("${upload.root-dir}")
    private String UPLOAD_ROOT_FOLDER;
    @Autowired
    private SysFileService sysFileService;
    @Autowired
    private SbInfoService sbInfoService;
    @Autowired
    private RepairApplicationFormService repairApplicationFormService;
    @Autowired
    private CheckJobService checkJobService;
    @Autowired
    private SbStatusLogService sbStatusLogService;
    /**
     * 通过id查询单条记录
     *
     * @param id 主键
     * @return R
     */
    @GetMapping("/sb/{id}")
    public R<SbInfoVO> getById(@PathVariable("id") String id) {
        return new R<>(sbInfoService.getById(id));
    }

    /**
     * 更新设备状态等其他信息
     *
     * @param id 主键
     * @return R
     */
    @PutMapping("/sb/status/{id}")
    public R update(@PathVariable("id") String id, @Validated({UpdateGroup.class}) @RequestBody SbInfoDTO sbInfoDTO) {
        sbInfoService.updateStatus(sbInfoDTO);
        return new R<>();
    }

    /**
     * 更新设备图片
     *
     * @param sbInfoDTO 设备基础信息DTO
     * @return R
     */
    @SysLog("更新设备图片信息")
    @PutMapping("/sb/images/{id}")
    public R updateImages(@PathVariable("id") String id, @Validated({UpdateGroup.class}) @RequestBody SbInfoDTO sbInfoDTO) {
        sbInfoService.modImagesByDTO(sbInfoDTO);
        return new R<>();
    }

    /**
     * 统计设备相关的任务
     * 保养任务
     * 维修任务
     *
     * @return R
     */
    @GetMapping("/sb/task/{sbId}")
    public R getSbTaskUser(@PathVariable("sbId") String sbId) {
        // 保养任务:根据类型查询，1：设备的、设备使用人的，未完成的，已过期的
        int lubricationTask = checkJobService.countTask(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 1);
        int lubricationTaskWeek = checkJobService.countTask(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 2);
        int lubricationTaskMonth = checkJobService.countTask(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 3);

        // 维修任务：所有的未完成的
        int repairTask = repairApplicationFormService.countTask(sbId, null,  1);
        return R.success(new GatherTaskVO()
                .setLubricationTask(lubricationTask)
                .setLubricationTaskWeek(lubricationTaskWeek)
                .setLubricationTaskMonth(lubricationTaskMonth)
                .setRepairTask(repairTask));
    }

    /**
     * 统计设备相关的任务
     * 保养任务
     * 维修任务
     *
     * @return R
     */
    @GetMapping("/sb/task2/{sbId}")
    public R getSbTaskUser2(@PathVariable("sbId") String sbId) {
        // 保养任务:根据类型查询，1：设备的、设备使用人的，未完成的，已过期的
        int lubricationTask = checkJobService.countTask2(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 1);
        int lubricationTaskWeek = checkJobService.countTask2(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 2);
        int lubricationTaskMonth = checkJobService.countTask2(sbId, null, CheckStandardTypeEnum.POLLING.getValue(), 3);

        // 维修任务：所有的未完成的
        int repairTask = repairApplicationFormService.countTask(sbId, null,  1);
        return R.success(new GatherTaskVO()
                .setLubricationTask(lubricationTask)
                .setLubricationTaskWeek(lubricationTaskWeek)
                .setLubricationTaskMonth(lubricationTaskMonth)
                .setRepairTask(repairTask));
    }

    /**
     * 新增记录
     *
     * @param repairApplicationFormDTO 保修单DTO
     * @return R
     */
    @SysLog("新增保修单")
    @PostMapping("/repair/add")
    public R saveIgnore(@Validated({AddGroup.class}) @RequestBody RepairApplicationFormDTO repairApplicationFormDTO) {
        return new R<>(repairApplicationFormService.saveModelByDTO(repairApplicationFormDTO));
    }

    /**
     * 通过id查询单条任务
     *
     * @param id 主键
     * @return R
     */
    @GetMapping("/check/jobs/{id}")
    public R<CheckJobVO> getCheckJobById(@PathVariable("id") String id){
        return new R<>(checkJobService.getDetail(id));
    }

    /**
     * 获取移动端保养任务分页
     * 我的任务和设备详情里面的任务
     * 我的任务：
     *  如果是现场人员的，则是当日的,和过期的
     *  如果是维修人员的，则是当月的,和过期的
     *
     * 设备详情里面：
     *  当日现场保养现场任务：则是当日的,和过期的
     *  当月保养任务：则是当月的,和过期的
     *
     *  功能里面的保养管理，则是全部的，调用上面一个接口，不是这个接口
     *
     * @param pageNum 当前页码
     * @param pageSize 每页条数
     * @param checkJobDTO 点检任务DTO
     * @return R
     */
    public R<AbstractPageResultBean<CheckJobVO>> query(CheckJobDTO checkJobDTO, @RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "20") int pageSize) {
        return new R<>(checkJobService.selectPageListMobile(checkJobDTO, pageNum, pageSize));
    }

    /**
     * 接收点检任务
     *
     * @param checkJobDTO 点检任务DTO
     * @return R
     */
    @SysLog("接收点检任务")
    @PutMapping("/check/jobs/execute")
    public R executeJob(@Validated({UpdateGroup.class}) @RequestBody CheckJobDTO checkJobDTO) {
        checkJobService.executeJobIgnore(checkJobDTO.getId());
        return new R<>();
    }

    /**
     * 完成任务
     *
     * @param checkJobDTO 点检任务DTO
     * @return R
     */
    @SysLog("完成点检任务")
    @PutMapping("/check/jobs/finish")
    public R finishJob(@Validated({UpdateGroup.class}) @RequestBody CheckJobDTO checkJobDTO) {
        checkJobService.finishJobIgnore(checkJobDTO);
        return new R<>();
    }

    /**
     * 获取月日历任务列表
     *
     * @param checkJobDTO 点检任务DTO
     * @return R
     */
    @GetMapping("/check/jobs/tuiCalendar")
    public R queryTuiCalendar(CheckJobDTO checkJobDTO) {
        return new R<>(checkJobService.getTuiCalendar(checkJobDTO));
    }

    /**
     * 文件上传
     *
     * @param file 文件
     * @return :
     */
    @SysLog("无需登录文件上传")
    @PostMapping("/files/upload")
    public R doUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return R.error("请选择一个上传文件");
        }
        FileVO fileVO = new FileVO();

        String fileFullName = file.getOriginalFilename();

        if (StringUtils.isNotBlank(fileFullName)) {
            fileFullName = fileFullName.replace(",", "，");
            fileVO.setName(fileFullName);
            int endIndex = fileFullName.lastIndexOf(".");
            fileVO.setFileName(fileFullName.substring(0, endIndex));
            fileVO.setFileFormat(fileFullName.substring(endIndex + 1));
            String fileType = fileFullName.substring(endIndex);
            String path = CommonConstants.RESOURCE_PREFIX + "/" + fileVO.getFileFormat() + "/" + DateUtil.formatDate(new Date()) + "/" + IdGeneratorUtils.getObjectId() + "/";
            String filePath = UPLOAD_ROOT_FOLDER + path;
            fileVO.setUrl(path + fileFullName);
            fileVO.setFileFormat(fileType);
            try {
                if (fileVO.getFileFormat().contains("png") || fileVO.getFileFormat().contains("JPEG")
                        || fileVO.getFileFormat().contains("jpg") || fileVO.getFileFormat().contains("jpeg")
                        || fileVO.getFileFormat().contains("PNG") || fileVO.getFileFormat().contains("JPG")) {
                    File targetFile = new File(filePath);
                    if (!targetFile.exists()) {
                        targetFile.mkdirs();
                    }
                    FileOutputStream out = new FileOutputStream(filePath + fileFullName);
                    Thumbnails.of(file.getInputStream()).scale(1).outputQuality(0.2)
                            .outputFormat(fileFullName.substring(endIndex + 1)).toOutputStream(out);
                    out.flush();
                    out.close();
                } else {
                    FileUtils.uploadFile(file.getBytes(), filePath, fileFullName);
                }
            } catch (Exception e) {
                return R.error("上传文件失败：" + e.getMessage());
            }
        }
        return R.success(fileVO, "上传成功");
    }

    /**
     * 新增记录
     *
     * @param sbStatusLogDTO 设备状态变更记录DTO
     * @return R
     */
    @SysLog("新增设备状态变更记录")
    @PostMapping("/sb/status-logs")
    public R save(@Validated({AddGroup.class}) @RequestBody SbStatusLogDTO sbStatusLogDTO) {
        return new R<>(sbStatusLogService.saveModelByDTOAndUserInfo(sbStatusLogDTO, null));
    }
}
